// 导入vscode全局对象
const vscode = require('vscode')
const { TextDocument, Position } = vscode

/**
 * 生成指定字符的替换函数
 */
const replacer = (char) => (raw) => char.repeat(raw.length)

/**
 * 获取标签的起始位置
 * 如果不在标签中返回 null
 * @param text
 * @param pos
 */
function getBracketRange(text, pos) {
  const textBeforePos = text.substr(0, pos)
  const startBracket = textBeforePos.lastIndexOf('<')
  if (
    startBracket < 0 ||
    textBeforePos[startBracket + 1] === '!' ||
    textBeforePos.lastIndexOf('>') > startBracket
  ) {
    return null
  }

  let endBracket = text.indexOf('>', pos + 1)
  if (endBracket < 0) {
    endBracket = text.length
  }
  const nextStart = text.indexOf('<', pos + 1)
  if (nextStart > 0 && nextStart < endBracket) {
    endBracket = nextStart
  }
  return [startBracket, endBracket - startBracket]
}
function getAttrName(str) {
  if (/\s([\w-:.]+)=%*$/.test(str)) {
    return RegExp.$1
  }
  return ''
}

// 也可以是以 @ 开头的字符，触发事件
const TAG_ATTR_REGEXP = /^(@|@?[\w-:.]+)\s*(=\s*("[^"]*"|'[^']*'|\w+))?\s*/
function getAttrs(text) {
  let attrs = {}
  getAttrs2(text, attrs)
  return attrs
}
function getAttrs2(text, attrs) {
  return match(text, TAG_ATTR_REGEXP, (m) => {
    attrs[stripColon(m[1])] = m[2] ? strip(m[3]) : true

    // 记录原生的末修改过的字段
    attrs['__' + m[1]] = m[2] ? m[3] : true
  })
}

function stripColon(name) {
  return name.replace(/\..*$/, '') // 去除修饰字符，如 .default, .stop, .user, .sync
}

function strip(val) {
  return val.replace(/^['"]|['"]$/g, '')
}

function match(str, reg, cb) {
  let mat
  while (str.length && (mat = str.match(reg))) {
    if (cb(mat)) break
    str = str.slice(mat[0].length)
  }

  return str
}

/**
 * 提取标签
 * @param doc
 * @param pos
 */
export function getValueTag(doc = TextDocument, pos = Position) {
  let offset = doc.offsetAt(pos)
  let text = doc.getText()
  let pureText = text.replace(/\{\{[^\}]*?\}\}/g, replacer('^'))
  let attrFlagText = pureText.replace(/("[^"]*"|'[^']*')/g, replacer('%')) // 将引号中的内容也替换了

  // 标签起始位置
  const range = getBracketRange(attrFlagText, offset)
  if (!range) {
    return null
  }
  const [start, end] = range

  offset = offset - start
  text = text.substr(start, end)
  attrFlagText = attrFlagText.substr(start, end)

  const tagNameMatcher = attrFlagText.match(/^<([\w-:.]+)/)
  if (!tagNameMatcher) {
    return null
  }
  const name = tagNameMatcher[1] // 标签名称
  const posWord = inputWordRange ? doc.getText(inputWordRange) : '' // 正在输入的词
  const isOnTagName = offset <= name.length + 1

  const attrName = isOnAttrValue
    ? getAttrName(attrFlagText.substring(0, offset))
    : '' // 当前输入对应的属性
  const isOnAttrValue = attrFlagText[offset] === '%'
  const isOnAttrName = !isOnTagName && !isOnAttrValue && !!posWord
  return {
    name,
    attrs: getAttrs((attrstr || '').trim()),
    posWord,
    isOnAttrName,
    isOnTagName,
    attrName,
  }
}
